﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;
using DoubleH.Utility;
using System.Threading;
using System.Diagnostics;
using DoubleH.Utility.Configuration;
using FCNS.Data;

namespace DoubleH.Utility.IO
{
    public enum FileType
    {
        传输文件,
        请求文件,
        删除文件
    }

    public class FileFormat
    {
        public FileType FileFlag { get; set; }
        public string IP { get; set; }
        public string Port { get; set; }
        string sourceIP = string.Empty;
        public string SourceIP { get { return sourceIP; } set { sourceIP = value; } }
        /// <summary>
        /// 用数据表名作为文件保存的目录名
        /// </summary>
        public string TableName { get; set; }
        public string FilePath { get; set; }
        public string FileName { get; set; }

        internal int PackSize { get; set; }
        internal int LastPackSize { get; set; }
        internal int PackCount { get; set; }
        internal long FileSize { get; set; }
    }


    public class TransferFiles
    {

        delegate void dStartSendFile(FileFormat file);

        //private static void StartSendFile(FileFormat file)
        //{
        //    try
        //    {
        //        ////设置进度条
        //        //if (Sate == true)
        //        //{

        //        //    if (Convert.ToInt32(PackCount) > 0)
        //        //    {
        //        //        D_UpFileSendProgressMax _D_UpFileSendProgressMax = new D_UpFileSendProgressMax(UpFileSendProgressMax);
        //        //        this.BeginInvoke(_D_UpFileSendProgressMax, new object[] { Convert.ToInt32(PackCount) });
        //        //    }
        //        //    else
        //        //    {
        //        //        D_UpFileSendProgressMax _D_UpFileSendProgressMax = new D_UpFileSendProgressMax(UpFileSendProgressMax);
        //        //        this.BeginInvoke(_D_UpFileSendProgressMax, new object[] { 1 });
        //        //    }

        //        //}
        //        //指向远程服务器
        //        IPEndPoint iped = new IPEndPoint(IPAddress.Parse(file.IP), int.Parse(file.Port));
        //        //创建套接字
        //        Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        //        //连接到远程服务器
        //        client.Connect(iped);

        //        IPEndPoint clientep = (IPEndPoint)client.RemoteEndPoint;

        //        //MsgLog.Items.Add();
        //        //D_UpMsgLog _D_UpMsgLog = new D_UpMsgLog(UpMsgLog);
        //        //this.BeginInvoke(_D_UpMsgLog, new object[] { System.DateTime.Now.ToString() + ":发送文件【" + FileName + "】->[" + clientep.Address.ToString() + "]" });

        //        //发送文件标识 
        //        SendVarData(client, System.Text.Encoding.Unicode.GetBytes(file.FileFlag.ToString()));
        //        //发送源地址
        //        SendVarData(client, System.Text.Encoding.Unicode.GetBytes(file.SourceIP));
        //        //发送文件夹名称
        //        SendVarData(client, System.Text.Encoding.Unicode.GetBytes(file.DirectoryName));
        //        //发送文件名
        //        SendVarData(client, System.Text.Encoding.Unicode.GetBytes(file.FileName));
        //        //发送文件大小
        //        SendVarData(client, System.Text.Encoding.Unicode.GetBytes(file.FileSize.ToString()));
        //        //发送包的大小
        //        SendVarData(client, System.Text.Encoding.Unicode.GetBytes(file.PackSize.ToString()));
        //        //发送包的数量
        //        SendVarData(client, System.Text.Encoding.Unicode.GetBytes(file.PackCount.ToString()));
        //        //发送最后一个包的大小
        //        SendVarData(client, System.Text.Encoding.Unicode.GetBytes(file.LastPackSize.ToString()));
        //        //发送文件MD5值
        //        //NetClassLibrary.SendVarData(client, System.Text.Encoding.Unicode.GetBytes(Text_FileMD5.Text.ToString()));
        //        System.IO.FileInfo tmp_FileInfo = new System.IO.FileInfo(file.FilePath);
        //        //打开文件
        //        System.IO.FileStream _fileStream = tmp_FileInfo.OpenRead();

        //        //定义数据包
        //        byte[] SendbagData = new byte[50000];//这个数值调整有什么用?

        //        //开始循环发送数据包
        //        for (int i = 0; i < file.PackCount; i++)
        //        {
        //            //从文件流中读取指定大小的数据，并填充到SendbagData字节变量中
        //            _fileStream.Read(SendbagData, 0, SendbagData.Length);
        //            //发送读取的数据包
        //            SendVarData(client, SendbagData);
        //            //if (Sate == true)
        //            //{
        //            //    //更新发包的数量(文本框中显示)
        //            //    D_UpSendBagNu _D_UpSendBagNu = new D_UpSendBagNu(UpSendBagNu);
        //            //    this.BeginInvoke(_D_UpSendBagNu, new object[] { (i + 1).ToString() });

        //            //    //更新进度条
        //            //    FileSendProgressB B = new FileSendProgressB(UpB);
        //            //    this.BeginInvoke(B, new object[] { i + 1 });
        //            //}
        //        }

        //        if (file.LastPackSize != 0)
        //        {
        //            //读取最后一个包
        //            SendbagData = new byte[file.LastPackSize];
        //            //发送最后一个包
        //            _fileStream.Read(SendbagData, 0, SendbagData.Length);
        //            SendVarData(client, SendbagData);
        //            //if (Sate == true)
        //            //{
        //            //    if (Convert.ToInt32(PackCount) == 0)
        //            //    {
        //            //        //更新进度条
        //            //        FileSendProgressB B = new FileSendProgressB(UpB);
        //            //        this.BeginInvoke(B, new object[] { 1 });
        //            //    }
        //            //}
        //        }
        //        //发送文件MD5值
        //        // NetClassLibrary.SendVarData(client, System.Text.Encoding.Unicode.GetBytes(Text_FileMD5.Text.ToString()));
        //        //关闭读取的文件
        //        _fileStream.Close();
        //        //关闭网络连接
        //        client.Close();
        //        //D_SendBtState _D_SendBtState = new D_SendBtState(SendBtState);
        //        //this.BeginInvoke(_D_SendBtState, new object[] { true });
        //    }
        //    catch (Exception ex)
        //    {
        //        MessageWindow.Show(ex.Message);
        //    }
        //}

        //private static int SendData(Socket s, byte[] data)
        //{
        //    int total = 0;
        //    int size = data.Length;
        //    int dataleft = size;
        //    int sent;

        //    while (total < size)
        //    {
        //        sent = s.Send(data, total, dataleft, SocketFlags.None);
        //        total += sent;
        //        dataleft -= sent;
        //    }

        //    return total;
        //}

        //private static byte[] ReceiveData(Socket s, int size)
        //{
        //    int total = 0;
        //    int dataleft = size;
        //    byte[] data = new byte[size];
        //    int recv;
        //    while (total < size)
        //    {
        //        recv = s.Receive(data, total, dataleft, SocketFlags.None);
        //        if (recv == 0)
        //        {
        //            data = null;
        //            break;
        //        }

        //        total += recv;
        //        dataleft -= recv;
        //    }
        //    return data;
        //}

        private static int SendVarData(Socket s, byte[] data)
        {
            int total = 0;
            int size = data.Length;
            int dataleft = size;
            int sent;
            byte[] datasize = new byte[4];
            datasize = BitConverter.GetBytes(size);
            sent = s.Send(datasize);

            while (total < size)
            {
                sent = s.Send(data, total, dataleft, SocketFlags.None);
                total += sent;
                dataleft -= sent;
            }

            return total;
        }


        public static bool SaveFile(FileFormat file)
        {
            try
            {
                if (!File.Exists(file.FilePath))
                    return false;

                try
                {
                    //保存附件到服务器的同时,本机备份一份,避免重复读取服务器
                    if (File.Exists(file.FilePath))
                        File.Copy(file.FilePath, DbDefine.dataDir + file.TableName + "\\" + file.FileName, true);
                }
                catch
                {
                    MessageWindow.Show("本机文件写入错误");
                }
                SaveRemoteFile(file);
            }
            catch
            {
                MessageWindow.Show("服务器写入权限不足-" + @"\\" + file.IP + "\\doubleH$\\" + file.TableName + "\\" + file.FileName);
                return false;
            }
            return true;
        }

        private static void SaveRemoteFile(FileFormat file)
        {
            string serverPath = SQLdata.SqlConfig.IPorName;
            if (string.IsNullOrEmpty(serverPath)||!serverPath.StartsWith(@"\\") || !char.IsDigit(serverPath[0]))
                return;

            //File.Copy(file.FilePath, @"\\" + file.IP + "\\doubleH$\\" + file.DirectoryName + "\\" + file.FileName, true);

        }

        private static string GetRemoteFile(FileFormat file)
        {
            //    string str = @"\\" + DoubleHConfig.AppConfig.ServerIP + "\\doubleH$\\" + file.DirectoryName + "\\" + file.FileName;
            //try
            //{
            //    if (File.Exists(str))
            //        return str;
            //    else
            //        return null;
            //}
            //catch
            //{
            //    MessageWindow.Show("服务器读取权限不足-"+str);
            return null;
            //}
        }

        public static string GetFile(FileFormat file)
        {
            string str = DbDefine.dataDir + file.TableName + "\\" + file.FileName;
            if (!File.Exists(str))
            {
                //如果本机不存在文件,尝试读取服务器,如果存在则拷贝一份到本机
                string remoteFile = GetRemoteFile(file);
                if (!string.IsNullOrEmpty(remoteFile))
                    File.Copy(remoteFile, str, true);
                else
                    str = string.Empty;
            }
            return str;
        }


        public static bool RemoveFile(string directory, string fileName)
        {
            string str = @"\\" + DoubleHConfig.AppConfig.ServerIP + "\\doubleH$\\" + directory + "\\" + fileName;
            try
            {
                bool success = false;
                if (File.Exists(str))
                {
                    File.Delete(str);
                    success = true;
                }
                return success;
            }
            catch
            {
                MessageWindow.Show(str + " 服务器移除权限不足-"+str);
                return false;
            }
        }
    }
}